<?php
    namespace App\common;

	use App\Models\Staff\cStaffRole;
	use App\Models\Staff\cStaffPermission;

	
	/* developer	: BREEZEER
	 * date			: 2022/6/23
	 * description	: combine permission bits for read write modify delete
	 *
	 *
	 *
	 *
	 *
	 *
	 */
	trait tiPermissionCheck 
	{
		/* on permission verified error then notify caller
		 *
		 */
		public function setOnErrorVerifiedPermission($on_callback_for_onErrorVerifiedPermission=null)
		{
			$this->on_callback_for_onErrorVerifiedPermission = $on_callback_for_onErrorVerifiedPermission;

			#
			#
			return $this;
		}
		private function onErrorVerifiedPermission	($o/* error object */)
		{
			if(is_callable(@$this->on_callback_for_onErrorVerifiedPermission))
			{
				($this->on_callback_for_onErrorVerifiedPermission)($o);								# notify caller
			}

			#
			#
			return $this;
		}

		public function permissionCheck($one_route_method_ooo){
			
			$this->m_cHelper						= app()->gcHelper							;
			$this->m_cStaffRole						= new cStaffRole()							;	# staff role
			$this->m_controller_method				= $one_route_method_ooo->controller_method	;	# current route method
			$this->m_user_id						= $one_route_method_ooo->user_id			;	# user id

			# 获取路由方法需要的权限
			#
			$permission								= (object)['controller_info'=>$one_route_method_ooo];
			$read									= (object)@$this->m_ar_read		[$this->m_controller_method];	if(!$this->m_cHelper->gfIsObjectEmpty($read		)){$permission->flag='read'		;$permission->data = $read	;}
			$write									= (object)@$this->m_ar_write	[$this->m_controller_method];	if(!$this->m_cHelper->gfIsObjectEmpty($write	)){$permission->flag='write'	;$permission->data = $write	;}
			$modify									= (object)@$this->m_ar_modify	[$this->m_controller_method];	if(!$this->m_cHelper->gfIsObjectEmpty($modify	)){$permission->flag='modify'	;$permission->data = $modify;}
			$delete									= (object)@$this->m_ar_delete	[$this->m_controller_method];	if(!$this->m_cHelper->gfIsObjectEmpty($delete	)){$permission->flag='delete'	;$permission->data = $delete;}

			# 当前的路由方法需要权限验证吗 ?
			#
			if($this->m_cHelper->gfIsObjectEmpty(@$permission->data))
			{
				return true;																							# 不需要访问权限立马放行
			}
			else
			{
				foreach($permission->data as $k => $v){$permission->data->$k['data_permission_verified_ok']	= false;}	# 有权限要求现在将每一个权限数据位校验标识的默认值设置为	=> false
			}

			# 获取用户拥有的所有权限
			#
			{
				$staff_all_role_and_permission_ooo		= (object)[];
				$staff_all_role_and_permission			= $this->m_cStaffRole->getStaffOwnAllRoleAndPermission($this->m_user_id);if($staff_all_role_and_permission===false){}else{$staff_all_role_and_permission_ooo = (object)$staff_all_role_and_permission;}
			}

			# 校验权限和权限数据位
			#
			#
			if(!$this->m_cHelper->gfIsObjectEmpty($staff_all_role_and_permission_ooo))
			{
				foreach($permission->data as $k => $one_permission) 
				{
					$one_permission_ooo					= (object)$one_permission;foreach($staff_all_role_and_permission_ooo->role_and_permission as $one_auth)
					{
						# 检查职员权限列表当中是否包含了路由方法需要的权限
						#
						$one_auth_ooo					= (object)$one_auth;if($one_auth_ooo->auth_code/* 职员拥有的权限 */ == $one_permission_ooo->auth_code/* 路由方法需要的权限 */) 
						{
							# 成功匹配到需要的权限再检查数据权限位是否许可
							#
							if(($one_permission_ooo->data_permission & $one_auth_ooo->auth_value) == $one_permission_ooo->data_permission) {$permission->data->$k['data_permission_verified_ok'] = true;}
						}
					}
				}

				# 路由方法对应的每一个数据权限位都验证成功了吗 ?
				#
				#
				$data_permission_verified_ok			= true;foreach($permission->data as $one_permission) 
				{
					$one_permission_ooo					= (object)$one_permission;if($one_permission_ooo->data_permission_verified_ok===false)
					{
						# 存在数据权限位没有通过验证立刻断言该用户无法访问此路由方法
						#
						$data_permission_verified_ok	= false;

						#
						#
						break;
					}
				}

				# 数据权限位全部验证通过,立马放行
				#
				if($data_permission_verified_ok)
				{
					return true;
				}
			}

			# verify permission and data bits failed then notify caller
			#
			$this->onErrorVerifiedPermission(
												(object)	[
																'route_method_need_permisssion'	=> (array) $permission							,	# 路由方法需要的权限名称和数据位
																'staff_hold_all_permission'		=> (array) $staff_all_role_and_permission_ooo	,	# 职员拥有的权限名称和数据位
															]
											);

			#
			#
			return  false;
		}
		
		# data permission bits collection
		#
		public function canRead		($ar_read	)	{	$this->m_ar_read	= $ar_read	;return $this;}	# read		 
		public function canWrite	($ar_write	)	{	$this->m_ar_write	= $ar_write	;return $this;}	# write		 
		public function canModify	($ar_modfiy	)	{	$this->m_ar_modify	= $ar_modfiy;return $this;} # modify	 
		public function canDelete	($ar_delete	)	{	$this->m_ar_delete	= $ar_delete;return $this;} # delete	 
	}
